/*
 * @Author: wangwei wwdqq7@qq.com
 * @Date: 2022-08-14 19:51:40
 * @LastEditors: wangwei wwdqq7@qq.com
 * @LastEditTime: 2025-04-01 16:38:43
 * @FilePath: /FullStack/pro/typeorm-mysql/src/user/user.controller.ts
 * @Description: 用户控制器，提供用户管理和权限控制的API接口
 * - 用户管理接口
 * - 角色分配接口
 * - 表级和数据库级权限管理接口
 */
import {
  Body,
  Controller,
  Delete,
  Get,
  HttpCode,
  HttpStatus,
  Param,
  ParseIntPipe,
  Post,
  Put,
  Query,
  UseGuards,
} from '@nestjs/common';
import {
  ApiBody,
  ApiOperation,
  ApiParam,
  ApiResponse,
  ApiTags,
} from '@nestjs/swagger';

import { RequirePermissions } from '@/auth/decorators/permissions.decorator';
import { JwtAuthGuard } from '@/auth/guards/jwt-auth.guard';
import { PermissionsGuard } from '@/auth/guards/permissions.guard';
import {
  DatabaseAccessDto,
  DatabaseAccessResponseDto,
  PermissionCheckResponseDto,
  TableAccessDto,
  TableAccessResponseDto,
} from '@/dto/access.dto';
import { CreateUserDto, UpdateUserDto, UserResponseDto } from '@/dto/user.dto';
import { UserService } from '@/user/user.service';

@ApiTags('用户管理')
@Controller('user')
@UseGuards(JwtAuthGuard)
export class UserController {
  constructor(private userService: UserService) {}

  // 用户基本CRUD操作
  @ApiOperation({
    summary: '获取所有用户',
    description: '获取系统中所有用户的列表',
  })
  @ApiResponse({
    status: 200,
    description: '成功获取用户列表',
    type: [UserResponseDto],
  })
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @RequirePermissions('SELECT')
  @Get()
  async getUsers() {
    return this.userService.getUsers();
  }

  @ApiOperation({
    summary: '获取指定用户',
    description: '根据用户ID获取用户信息',
  })
  @ApiParam({ name: 'id', description: '用户ID' })
  @ApiResponse({
    status: 200,
    description: '成功获取用户信息',
    type: UserResponseDto,
  })
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @RequirePermissions('SELECT')
  @Get(':id')
  async getUserById(@Param('id', ParseIntPipe) id: number) {
    return this.userService.getUserById(id);
  }

  @ApiOperation({ summary: '创建新用户', description: '创建一个新的用户账户' })
  @ApiBody({ type: CreateUserDto })
  @ApiResponse({
    status: 201,
    description: '用户创建成功',
    type: UserResponseDto,
  })
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @RequirePermissions('INSERT')
  @Post()
  @HttpCode(HttpStatus.CREATED)
  async addUser(@Body() userData: CreateUserDto) {
    return this.userService.addUser(userData);
  }

  @ApiOperation({ summary: '更新用户信息', description: '更新指定用户的信息' })
  @ApiParam({ name: 'id', description: '用户ID' })
  @ApiBody({ type: UpdateUserDto })
  @ApiResponse({
    status: 200,
    description: '用户信息更新成功',
    type: UserResponseDto,
  })
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @RequirePermissions('UPDATE')
  @Put(':id')
  async updateUser(
    @Param('id', ParseIntPipe) id: number,
    @Body() userData: UpdateUserDto,
  ) {
    return this.userService.updateUser(id, userData);
  }

  @ApiOperation({ summary: '删除用户', description: '删除指定的用户账户' })
  @ApiParam({ name: 'id', description: '用户ID' })
  @ApiResponse({ status: 200, description: '用户删除成功' })
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @RequirePermissions('DELETE')
  @Delete(':id')
  async deleteUser(@Param('id', ParseIntPipe) id: number) {
    return this.userService.deleteUser(id);
  }

  // 用户角色管理
  @ApiOperation({
    summary: '获取用户角色',
    description: '获取指定用户拥有的所有角色',
  })
  @ApiParam({ name: 'id', description: '用户ID' })
  @ApiResponse({ status: 200, description: '成功获取用户角色列表' })
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @RequirePermissions('SELECT')
  @Get(':id/roles')
  async getUserRoles(@Param('id', ParseIntPipe) id: number) {
    return this.userService.getUserRoles(id);
  }

  @ApiOperation({
    summary: '分配角色给用户',
    description: '为指定用户分配一个角色',
  })
  @ApiParam({ name: 'userId', description: '用户ID' })
  @ApiParam({ name: 'roleId', description: '角色ID' })
  @ApiResponse({ status: 200, description: '角色分配成功' })
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @RequirePermissions('INSERT')
  @Post(':userId/roles/:roleId')
  async assignRoleToUser(
    @Param('userId', ParseIntPipe) userId: number,
    @Param('roleId', ParseIntPipe) roleId: number,
  ) {
    return this.userService.assignRoleToUser(userId, roleId);
  }

  @ApiOperation({
    summary: '移除用户角色',
    description: '移除指定用户的一个角色',
  })
  @ApiParam({ name: 'userId', description: '用户ID' })
  @ApiParam({ name: 'roleId', description: '角色ID' })
  @ApiResponse({ status: 200, description: '角色移除成功' })
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @RequirePermissions('DELETE')
  @Delete(':userId/roles/:roleId')
  async removeRoleFromUser(
    @Param('userId', ParseIntPipe) userId: number,
    @Param('roleId', ParseIntPipe) roleId: number,
  ) {
    return this.userService.removeRoleFromUser(userId, roleId);
  }

  // 表级权限管理
  @ApiOperation({
    summary: '获取用户表级权限',
    description: '获取指定用户拥有的所有表级权限',
  })
  @ApiParam({ name: 'id', description: '用户ID' })
  @ApiResponse({
    status: 200,
    description: '成功获取用户表级权限列表',
    type: [TableAccessResponseDto],
  })
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @RequirePermissions('SELECT')
  @Get(':id/table-access')
  async getUserTableAccess(@Param('id', ParseIntPipe) id: number) {
    return this.userService.getUserTableAccess(id);
  }

  @ApiOperation({
    summary: '分配表级权限给用户',
    description: '为指定用户分配一个表级权限',
  })
  @ApiParam({ name: 'id', description: '用户ID' })
  @ApiBody({ type: TableAccessDto })
  @ApiResponse({
    status: 200,
    description: '表级权限分配成功',
    type: TableAccessResponseDto,
  })
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @RequirePermissions('INSERT')
  @Post(':id/table-access')
  async assignTableAccessToUser(
    @Param('id', ParseIntPipe) userId: number,
    @Body() tableAccessData: TableAccessDto,
  ) {
    const { permissionId, databaseName, tableName } = tableAccessData;
    return this.userService.assignTableAccessToUser(
      userId,
      permissionId,
      databaseName,
      tableName,
    );
  }

  @ApiOperation({
    summary: '移除用户表级权限',
    description: '移除指定用户的一个表级权限',
  })
  @ApiParam({ name: 'id', description: '用户ID' })
  @ApiBody({ type: TableAccessDto })
  @ApiResponse({ status: 200, description: '表级权限移除成功' })
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @RequirePermissions('DELETE')
  @Delete(':id/table-access')
  async removeTableAccessFromUser(
    @Param('id', ParseIntPipe) userId: number,
    @Body() tableAccessData: TableAccessDto,
  ) {
    const { permissionId, databaseName, tableName } = tableAccessData;
    return this.userService.removeTableAccessFromUser(
      userId,
      permissionId,
      databaseName,
      tableName,
    );
  }

  // 数据库级权限管理
  @ApiOperation({
    summary: '获取用户数据库级权限',
    description: '获取指定用户拥有的所有数据库级权限',
  })
  @ApiParam({ name: 'id', description: '用户ID' })
  @ApiResponse({
    status: 200,
    description: '成功获取用户数据库级权限列表',
    type: [DatabaseAccessResponseDto],
  })
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @RequirePermissions('SELECT')
  @Get(':id/database-access')
  async getUserDatabaseAccess(@Param('id', ParseIntPipe) id: number) {
    return this.userService.getUserDatabaseAccess(id);
  }

  @ApiOperation({
    summary: '分配数据库级权限给用户',
    description: '为指定用户分配一个数据库级权限',
  })
  @ApiParam({ name: 'id', description: '用户ID' })
  @ApiBody({ type: DatabaseAccessDto })
  @ApiResponse({
    status: 200,
    description: '数据库级权限分配成功',
    type: DatabaseAccessResponseDto,
  })
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @RequirePermissions('INSERT')
  @Post(':id/database-access')
  async assignDatabaseAccessToUser(
    @Param('id', ParseIntPipe) userId: number,
    @Body() databaseAccessData: DatabaseAccessDto,
  ) {
    const { permissionId, databaseName } = databaseAccessData;
    return this.userService.assignDatabaseAccessToUser(
      userId,
      permissionId,
      databaseName,
    );
  }

  @ApiOperation({
    summary: '移除用户数据库级权限',
    description: '移除指定用户的一个数据库级权限',
  })
  @ApiParam({ name: 'id', description: '用户ID' })
  @ApiBody({ type: DatabaseAccessDto })
  @ApiResponse({ status: 200, description: '数据库级权限移除成功' })
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @RequirePermissions('DELETE')
  @Delete(':id/database-access')
  async removeDatabaseAccessFromUser(
    @Param('id', ParseIntPipe) userId: number,
    @Body() databaseAccessData: DatabaseAccessDto,
  ) {
    const { permissionId, databaseName } = databaseAccessData;
    return this.userService.removeDatabaseAccessFromUser(
      userId,
      permissionId,
      databaseName,
    );
  }

  // 权限检查
  @ApiOperation({
    summary: '检查用户权限',
    description: '检查指定用户是否拥有对特定数据库表的操作权限',
  })
  @ApiResponse({
    status: 200,
    description: '权限检查结果',
    type: PermissionCheckResponseDto,
  })
  @UseGuards(JwtAuthGuard)
  @Get('check-permission')
  async checkUserTablePermission(
    @Query('userId', ParseIntPipe) userId: number,
    @Query('databaseName') databaseName: string,
    @Query('tableName') tableName: string,
    @Query('action') action: string,
  ) {
    return this.userService.checkUserTablePermission(
      userId,
      databaseName,
      tableName,
      action,
    );
  }
}
